/**
 * @file STL_MysqlConnPool.h
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2020-10-14
 * 
 * @copyright Copyright Sci-Tech Laboratories (c) 2020
 * 
 */

#ifndef _STL_MYSQL_CONN_POOL_H_
#define _STL_MYSQL_CONN_POOL_H_

#include <mysql/mysql.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <map>
#include <string>
#include <vector>

namespace STL
{
    class STL_Connection;

    class STL_Some
    {
    public:
        STL_Some() {}
        STL_Connection *first;
        bool second;
    };

    class STL_MysqlConnPool
    {
    public:
        static int initPool(std::string host, unsigned int port, std::string user, std::string passwd, std::string database, int poolSize);
        static void destroyPool();

        static STL_Connection *getConnection();
        static int releaseConnection(STL_Connection *);
        static void lock();
        static void unlock();

        static void locke();
        static void unlocke();

        static void locki();
        static void unlocki();

        static void lockl();
        static void unlockl();

    private:
        static pthread_mutex_t mutex;
        static pthread_mutex_t execmutex;
        static pthread_mutex_t initmutex;
        static pthread_mutex_t logmutex;
        static STL_MysqlConnPool *pool_;

    private:
        STL_Some *vec; // need an instance to init

    public:
        static std::string host_;
        static unsigned int port_;
        static std::string user_;
        static std::string passwd_;
        static std::string database_;
        static int poolSize_;

    public:
        STL_MysqlConnPool();
        virtual ~STL_MysqlConnPool();
    };

    class STL_QueryResult;

    class STL_Connection
    {
    public:
        STL_Connection(std::string host, unsigned int prot, std::string user, std::string passwd, std::string database);
        virtual ~STL_Connection();

        STL_QueryResult executeQuery(std::string statement, long tid);

    private:
        // MYSQL代表了一条TCP连接
        MYSQL *conn;
    };

    class STL_QueryResult
    {
    public:
        STL_QueryResult() : insert_id(0), affected_rows(0), sql_state(""), info(""), error_number(0), error_info(""), field_count(0)
        {
            fields.clear();
            string_table.clear();
        }

    public:
        int getRowCount() { return string_table.size(); }
        int getColumnCount() { return fields.size(); };
        std::string getField(int column) { return fields[column]; }
        std::string getElement(int row, int column) { return string_table[row][column]; }

        friend class STL_Connection;

    public::
        void addField(const std::string field) { fields.push_back(field); };

    public::
        my_ulonglong insert_id;
        my_ulonglong affected_rows; // (my_ulonglong)-1 为无效值
        std::string sql_state;
        std::string info;
        unsigned int error_number;
        std::string error_info;
        unsigned int field_count;
        std::vector<std::string> fields;
        std::vector<std::vector<std::string>> string_table; // 注意尖括号套用需要加空格 < <> >
    };

} // namespace STL
#endif // _STL_MYSQL_CONN_POOL_H_